package com.ctyon.watchmanager.service;

import android.app.PendingIntent;
import android.app.Service;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.os.Environment;
import android.os.IBinder;
import android.util.Log;
import android.widget.Toast;

import com.alibaba.fastjson.JSON;
import com.ctyon.common.event.ChatMessageEvent;
import com.ctyon.common.event.GetImgEvent;
import com.ctyon.common.event.HeartMessageEvent;
import com.ctyon.common.event.HfcxMessageEvent;
import com.ctyon.common.event.LocationMessageEvent;
import com.ctyon.common.event.UpdateApp;
import com.ctyon.common.util.DataUtil;
import com.ctyon.netlibrary.net.revert.BaseResponseEntity;
import com.ctyon.netlibrary.use.BaseObserver;
import com.ctyon.watchmanager.BasicApp;
import com.ctyon.watchmanager.R;
import com.ctyon.watchmanager.model.db.entity.ChatMessageEntity;
import com.ctyon.watchmanager.model.db.entity.LocationEntity;
import com.ctyon.watchmanager.model.net.service.NetService;
import com.ctyon.watchmanager.ui.activity.ChatActivity;
import com.ctyon.watchmanager.util.AppUtil;
import com.ctyon.watchmanager.util.LogUtil;
import com.ctyon.watchmanager.util.MyNotification;
import com.ctyon.watchmanager.util.OssUtil;
import com.orhanobut.logger.Logger;

import org.greenrobot.eventbus.EventBus;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

import androidx.annotation.Nullable;
import io.reactivex.Observable;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;
import lee.com.mqttlibrary.callback.MyMQTTCallback;
import lee.com.mqttlibrary.mqtt.MQTTManager;

/**
 * CreateDate：19-8-1 on 下午5:18
 * Describe:
 * Coder: lee
 */
public class BgService extends Service implements MyMQTTCallback {

    private static final String LTAG = "BgService";

    private static final String TYPE = "type";
    public static final String TYPE_MQTT = "type_mqtt";

    public static final String MESSAGE_CHAT = "text/audio/picture";
    public static final String MESSAGE_LK = "LK";
    public static final String MESSAGE_UD = "UD";
    public static final String MESSAGE_IMG = "img";
    public static final String MESSAGE_HFCXN = "HFCXN";

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        Logger.t(LTAG).d("onCreate");
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        if (null != intent) {
            String type = intent.getStringExtra(TYPE);
            if (DataUtil.isEmptyOr(type)) {
                checkUpdate();
            } else if (type.equals(TYPE_MQTT)) {
                MQTTManager.getInstance().setCallback(this);
                loadLocationHistory();
                loadChatMessage();
            } else {

            }
        }
        return super.onStartCommand(intent, flags, startId);
    }

    private void checkUpdate() {
        long version = Long.valueOf(AppUtil.getAppVersionName(BasicApp.getInstance().getApplicationContext()));
        Logger.t(LTAG).d("checkUpdate : version = " + version);
        final String method = "checkUpdate";
        if (NetService.getInstance().isDisable(method)) {
            return;
        }
        try {
            NetService.getInstance()
                    .method(method)
                    .checkUpdate(BasicApp.getInstance().getManager().getManagerId(), String.valueOf(version))
                    .timeout(10, TimeUnit.SECONDS)
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new BaseObserver<BaseResponseEntity>() {
                        @Override
                        public void onSuccess(BaseResponseEntity responseEntity) {
                            Logger.d("onSuccess : " + responseEntity.toString());
                            String data = responseEntity.data.toString();
                            if (Long.valueOf(data) > 0) {
                                download(data);
                            }
                        }

                        @Override
                        public String onOver() {
                            return method;
                        }
                    });
        } catch (Exception e) {
            Logger.t(LTAG).e("ERROR : " + e);
        }

    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Logger.t(LTAG).d("onDestroy");
    }

    private void download(String apk) {
        BasicApp.getInstance().getAppExecutors().networkIO().execute(() -> {
            try {
                OssUtil.getOssInstance().downloadApk(apk, path -> {
                    Logger.t(LTAG).d("downloadApk callback : path = " + path);
                    EventBus.getDefault().postSticky(new UpdateApp(path));
                });
            } catch (Exception e) {
                e.printStackTrace();
                Logger.t(LTAG).d("download : " + e);
            } finally {
            }
        });
    }

    public static void watchMqtt(Context context, String type) {
        Intent intent = new Intent(context, BgService.class);
        intent.putExtra(TYPE, type);
        context.startService(intent);
    }

    @Override
    public void mqttData(String topic, byte[] data) {
        Logger.t(LTAG).d("mqttData : topic = " + topic);
        String[] s = topic.split("/");
        if (null != s && s.length == 5) {
            String fromId = s[3];
            if (!DataUtil.isEmptyOr(fromId)) {
                String fromName = "";
                if (fromId.equals(String.valueOf(BasicApp.getInstance().getManager().getManagerId()))) {
                    Logger.t(LTAG).d("来自自己的消息");
                } else {
                    if (fromId.equals(BasicApp.getInstance().getWatch().getMeid())) {
                        fromName = BasicApp.getInstance().getWatch().getNick();
                    } else {
                        fromName = s[5];
                    }
                    String type = s[4];
                    Logger.t(LTAG).d("来自" + fromId + "的消息" + "  type = " + type);
                    if (MESSAGE_CHAT.contains(type)) {//微聊
                        ChatMessageEvent chatMessageEvent = new ChatMessageEvent(type, fromName, data);
                        EventBus.getDefault().post(chatMessageEvent);
                        String finalFromName = fromName;
                        BasicApp.getInstance().getAppExecutors().diskIO().execute(() -> {
                            ChatMessageEntity entity = new ChatMessageEntity(type, finalFromName, data, true);
                            BasicApp.getInstance().getRepository().insertChatMessage(entity);
                        });

                        String activity = AppUtil.getTopActivity(BasicApp.getInstance().getApplicationContext());
                        Logger.t(LTAG).i("top activity : " + activity);
                        if (DataUtil.isEmptyOr(activity) || !activity.equals("com.ctyon.watchmanager.ui.activity.ChatActivity")) {
                            MyNotification.getInstance()
                                    .setContentIntent(getPendingIntent())
                                    .sendNotification(MyNotification.CHAT_ID, "微聊", "收到新消息", R.mipmap.watch_icon);

                        }
                    } else if (MESSAGE_LK.contains(type)) {//心跳附带数据
                        HeartMessageEvent heartMessageEvent = new HeartMessageEvent(new String(data));
                        String step = heartMessageEvent.getStep();
                        String battery = heartMessageEvent.getBattery();
                        Logger.d("onHeartBeat : step = " + step + "  battery = " + battery);
                        BasicApp.getInstance().getWatch().setStep(Long.valueOf(step));
                        BasicApp.getInstance().getWatch().setBattery(Integer.valueOf(battery));
                        EventBus.getDefault().post(heartMessageEvent);
                    } else if (MESSAGE_UD.contains(type)) {//定位
                        LocationMessageEvent locationMessageEvent = new LocationMessageEvent(new String(data));
                        Logger.d("onLocation : location = " + locationMessageEvent.getLocation());
                        BasicApp.getInstance().getWatch().setLocation(locationMessageEvent.getLocation());
                        BasicApp.getInstance().getWatch().setLocationTime(locationMessageEvent.getTime());
                        EventBus.getDefault().post(locationMessageEvent);
                    } else if (MESSAGE_IMG.contains(type)) {
//                        Logger.d("onLocation : location = " + locationMessageEvent.getLocation());
                        GetImgEvent getImgEvent = new GetImgEvent();
                        getImgEvent.setType("getImage");
                        getImgEvent.setId(fromId);
                        EventBus.getDefault().post(getImgEvent);
//                        BytesUtil.unpackData(1, data);
                    } else if (MESSAGE_HFCXN.contains(type)) {
                        Log.e("androidLog11", DataUtil.unicode2String(new String(data)));
                        HfcxMessageEvent hfcxMessageEvent = new HfcxMessageEvent();
                        hfcxMessageEvent.setContent(DataUtil.unicode2String(new String(data)));
                        EventBus.getDefault().post(hfcxMessageEvent);
                    }
                }
            }
        }

    }

    @Override
    public void onMQTTError(int code, String err) {

    }

    @Override
    public void onMQTTResult(int type, boolean connect) {

    }

    private PendingIntent getPendingIntent() {

        // 设置通知的点击行为：这里启动一个 Activity
        Intent intent = new Intent(this, ChatActivity.class);
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);

        return pendingIntent;
    }

    private void loadLocationHistory() {

        Observable.create((ObservableOnSubscribe<Long>) emitter -> {
            String time = BasicApp.getInstance().getRepository().findLastLocationTime();
            Logger.t(LTAG).i("time = " + time);
            emitter.onNext(DataUtil.isEmptyOr(time) ? 0L : Long.valueOf(time));
        }).subscribeOn(Schedulers.newThread())
                .subscribe(time -> {

                    final String method = "getAllLocation";
                    if (NetService.getInstance().isDisable(method)) {
                        return;
                    }
                    NetService.getInstance()
                            .getAllLocation(BasicApp.getInstance().getManager().getManagerId(), BasicApp.getInstance().getWatch().getMeid(), time)
                            .timeout(10, TimeUnit.SECONDS)
                            .subscribe(new BaseObserver<BaseResponseEntity>() {
                                @Override
                                public void onSuccess(BaseResponseEntity responseEntity) {

                                    Logger.t(LTAG).d("onSuccess : " + responseEntity.toString());
                                    String data = responseEntity.data.toString().trim().replace("=", ":");
                                    try {
                                        List<LocationEntity> list = new ArrayList();
                                        JSONArray jsonArray = new JSONArray(data);
                                        String locationE = "";
                                        for (int i = 0; i < jsonArray.length(); i++) {
                                            JSONObject obj = jsonArray.getJSONObject(i);
                                            LocationEntity locationEneity = JSON.parseObject(obj.toString(), LocationEntity.class);
                                            String location = locationEneity.getLocation();
                                            if (location.equals(locationE)) {
                                                continue;
                                            }
                                            locationE = location;
                                            list.add(locationEneity);
                                        }

                                        if (list.size() > 0) {
                                            BasicApp.getInstance().getAppExecutors().diskIO().execute(() -> {
                                                BasicApp.getInstance().getRepository().insertLocations(list);
                                                Logger.t(LTAG).i("位置数据同步完成");
                                            });
                                        }

                                    } catch (JSONException e) {
                                        e.printStackTrace();
                                    }
                                }

                                @Override
                                public String onOver() {
                                    return method;
                                }
                            });
                });

    }

    private void loadChatMessage() {
        Observable.create((ObservableOnSubscribe<Long>) emitter -> {
            Long time = BasicApp.getInstance().getRepository().findLastChatTime();
            Logger.t(LTAG).i("time = " + time);
            emitter.onNext(null == time ? 0L : time);
        }).subscribeOn(Schedulers.newThread())
                .subscribe(time -> {
                    final String method = "loadChatMessage";
                    if (NetService.getInstance().isDisable(method)) {
                        return;
                    }
                    NetService.getInstance()
                            .loadChatMessage(BasicApp.getInstance().getWatch().getMeid(), time)
                            .timeout(10, TimeUnit.SECONDS)
                            .subscribe(new BaseObserver<BaseResponseEntity>() {
                                @Override
                                public void onSuccess(BaseResponseEntity responseEntity) {

                                    Logger.t(LTAG).d("onSuccess : " + responseEntity.toString());
//                                    String data = responseEntity.data.toString().trim().replace("=", ":");
//                                    try {
////                                        List<LocationEntity> list = new ArrayList();
//                                        JSONArray jsonArray = new JSONArray(data);
////                                        String locationE = "";
//                                        for (int i = 0; i < jsonArray.length(); i++) {
//                                            JSONObject obj = jsonArray.getJSONObject(i);
////                                            LocationEntity locationEneity = JSON.parseObject(obj.toString(), LocationEntity.class);
////                                            String location = locationEneity.getLocation();
////                                            if (location.equals(locationE)) {
////                                                continue;
////                                            }
////                                            locationE = location;
////                                            list.add(locationEneity);
//                                        }
//
////                                        if (list.size() > 0) {
////                                            BasicApp.getInstance().getAppExecutors().diskIO().execute(() -> {
////                                                BasicApp.getInstance().getRepository().insertLocations(list);
////                                                Logger.t(LTAG).i("位置数据同步完成");
////                                            });
////                                        }
//
//                                    } catch (JSONException e) {
//                                        e.printStackTrace();
//                                    }
                                }

                                @Override
                                public String onOver() {
                                    return method;
                                }
                            });
                });
    }

}
